Add new module 'axim_gpb', a track reader for Dell Axim Navigation System (.gpb)...
authoroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 7 May 2006 17:46:57 +0000 (17:46 +0000)
committeroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 7 May 2006 17:46:57 +0000 (17:46 +0000)
gpsbabel/axim_gpb.c [new file with mode: 0644]

diff --git a/gpsbabel/axim_gpb.c b/gpsbabel/axim_gpb.c
new file mode 100644 (file)
index 0000000..9a16fcf
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+
+    Track reader for "Dell Axim Navigation System" GPB files,
+
+    Copyright (C) 2006 Olaf Klein, o.b.klein@t-online.de
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+#include "defs.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MYNAME "axim_gpb"
+
+#define RECORD_LEN     344
+
+static FILE *fin, *fout;
+static char dbginfo = 1;
+
+static
+arglist_t axim_gpb_args[] = {
+       ARG_TERMINATOR
+};
+
+static float
+le_read32_float(const void *src)
+{
+       float f;
+       gbint32 i;
+       
+       i = le_read32(src);
+       memcpy(&f, &i, 4);
+       
+       return f;
+}
+
+static void
+decode_buff(const char *buff, route_head *track)
+{
+       struct tm tm;
+       double lat, lon, alt, dir;
+       float vdop, hdop, pdop, spd, Uf1;
+       int sats;
+       waypoint *wpt;
+       
+       wpt = waypt_new();
+       
+       memset(&tm, '\0', sizeof(tm));
+       
+       tm.tm_year = le_read16((void *) (buff + 16));
+       tm.tm_mon = le_read16((void *)  (buff + 18));
+       tm.tm_mday = le_read16((void *) (buff + 22));
+       tm.tm_hour = le_read16((void *) (buff + 24));
+       tm.tm_min = le_read16((void *)  (buff + 26));
+       tm.tm_sec = le_read16((void *)  (buff + 28));
+       
+       le_read64(&lat, (void *)        (buff + 32));
+       le_read64(&lon, (void *)        (buff + 40));
+       spd = le_read32_float((void *)  (buff + 48));
+       dir = le_read32_float((void *)  (buff + 52));
+
+       alt = le_read32_float((void *)  (buff + 64));
+       Uf1 = le_read32_float((void *)  (buff + 68));
+
+       hdop = le_read32_float((void *) (buff + 84));
+       vdop = le_read32_float((void *) (buff + 88));
+       pdop = le_read32_float((void *) (buff + 92));
+       sats = le_read16((void *)       (buff + 96));
+
+       wpt->latitude = lat;
+       wpt->longitude = lon;
+       wpt->altitude = alt;
+#if 0
+       /* These values can be, but must not be right. */
+       /* Further checks are needed to verify that. */
+       /*         (!!! reference data !!!)          */
+       wpt->course = dir;
+       wpt->hdop = hdop;
+       wpt->vdop = vdop;
+       wpt->pdop = pdop;
+       wpt->sat = sats;
+       wpt->speed = spd * 10;
+#endif
+       /* We don't have a header with some magic fixed numbers or strings. */
+       /* So let us check the range for some basic values */
+       
+       is_fatal(
+               (tm.tm_year < 2005) || 
+               (tm.tm_mon < 1) || (tm.tm_mon > 12) || 
+               (tm.tm_mday < 1) || (tm.tm_mday > 31) ||
+               (tm.tm_hour > 23) || (tm.tm_min > 60) || (tm.tm_sec > 60),
+               MYNAME ": Invalid or unsupported file (invalid time-stamp).");
+       is_fatal(
+               (fabs(wpt->latitude) > 180) ||
+               (fabs(wpt->longitude) > 90),
+               MYNAME ": Invalid or unsupported file (lat or/and lon out of range).");
+
+       /* post work */
+       
+       tm.tm_year-=1900;
+       tm.tm_mon--;
+       wpt->creation_time = mkgmtime(&tm);
+
+       track_add_wpt(track, wpt);
+}
+
+/*******************************************************************************
+* %%%        global callbacks called by gpsbabel main process              %%% *
+*******************************************************************************/
+
+static void
+axim_gpb_rd_init(const char *fname)
+{
+       fin = xfopen(fname, "rb", MYNAME);
+}
+
+static void 
+axim_gpb_rd_deinit(void)
+{
+       fclose(fin);
+}
+
+static void
+axim_gpb_read(void)
+{
+       char buff[RECORD_LEN];
+       route_head *track = NULL;
+       size_t bytes;
+       off_t filesize, left;
+
+       fseek(fin, 0, SEEK_END);
+       filesize = ftell(fin);
+
+       left = filesize - ((filesize / RECORD_LEN) * RECORD_LEN);
+       is_fatal((left != 0), MYNAME ": Invalid or unsupported file (filesize).");
+       
+       fseek(fin, 0, SEEK_SET);        /* seek file to start */
+       
+       while ((bytes = fread(buff, 1, RECORD_LEN, fin)))
+       {
+               if (track == NULL)
+               {
+                       track = route_head_alloc();
+                       track_add_head(track);
+               }
+               decode_buff(buff, track);
+       }
+}
+
+/**************************************************************************/
+
+ff_vecs_t axim_gpb_vecs = {
+       ff_type_file,
+       { 
+               ff_cap_none     /* waypoints */, 
+               ff_cap_read     /* tracks */, 
+               ff_cap_none     /* routes */, 
+       },
+       axim_gpb_rd_init,       
+       NULL,   
+       axim_gpb_rd_deinit,     
+       NULL,   
+       axim_gpb_read,
+       NULL,
+       NULL,
+       axim_gpb_args,
+       CET_CHARSET_ASCII, 0
+};
+/**************************************************************************/